﻿/*
   Copyright 2012 University of Southampton

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebControls;
using uk.ac.soton.ses.DAL;
using System.Web.UI;
using System.Collections;
using System.Web;
using System.Web.UI.HtmlControls;

namespace uk.ac.soton.ses.WebControls
{
    public class ExperimentParameterListViewLayoutTemplate : ITemplate
    {
        public void InstantiateIn(Control container)
        {
            //Create table with styling
            HtmlTable table = new HtmlTable();
            table.Attributes["class"] = "ExperimentParametersGrid";
            container.Controls.Add(table);

            //Create Header
            HtmlTableRow thead = new HtmlTableRow();
            thead.Controls.Add(this.CreateHeaderCell("Operations"));
            thead.Controls.Add(this.CreateHeaderCell("Name"));
            thead.Controls.Add(this.CreateHeaderCell("Value"));
            thead.Controls.Add(this.CreateHeaderCell("Compulsory"));
            thead.Controls.Add(this.CreateHeaderCell("Unit"));
            thead.Controls.Add(this.CreateHeaderCell("Type"));
            thead.Controls.Add(this.CreateHeaderCell("Position"));
            table.Controls.Add(thead);

            //HtmlTableRow insertrow = new HtmlTableRow();
            //HtmlTableCell newParamCell = new HtmlTableCell() { ColSpan = 7 };
            //insertrow.Attributes.Add("class", "ParameterPositionInsert");
            //insertrow.Controls.Add(newParamCell);
            //table.Controls.Add(insertrow);

            //Create item place holder (to be replaced by ListView ItemTemplate)
            HtmlTableRow tr = new HtmlTableRow() { ID = "itemPlaceHolder" };
            table.Controls.Add(tr);

        }

        /// <summary>
        /// Creates an HtmlTableCell TH cell with the specified title
        /// </summary>
        /// <param name="headerText">TH title</param>
        /// <returns>The new table cell</returns>
        private HtmlTableCell CreateHeaderCell(string headerText)
        {
            HtmlTableCell th = new HtmlTableCell("th");
            Literal thtext = new Literal() { Text = headerText };
            th.Controls.Add(thtext);
            return th;
        }

    }


    public class ExperimentParameterListViewItemTemplate: ITemplate
    {
        bool _editMode = false;
        private AssociateLinkButtonControl _associateLinkButton = null;
        private ParameterPositionControl _parameterPositionControl = null;

        public ExperimentParameterListViewItemTemplate(bool editMode)
        {
            this._editMode = editMode;
        }

        public void InstantiateIn(Control container)
        {
            //Put everything in a container that can be added to later when data binding
            PlaceHolder controlsPlaceHolder = new PlaceHolder() { ID = "ControlsContainer" };
            container.Controls.Add(controlsPlaceHolder);

            HtmlTableRow rowforinsert = new HtmlTableRow();
            HtmlTableCell newParamCell = new HtmlTableCell() { ColSpan = 7 };
            rowforinsert.Attributes.Add("class", "ParameterPositionInsert");
            rowforinsert.Controls.Add(newParamCell);
            controlsPlaceHolder.Controls.Add(rowforinsert);

            //Create a new row for our data
            TableRow row = new TableRow();
            controlsPlaceHolder.Controls.Add(row);
            row.ID = "parameterrow";
            row.CssClass = "parameterrow";

            //Create operations column
            TableCell tdOperations = new TableCell() { ID = "tdOperations" };
            row.Controls.Add(tdOperations);

            //Create buttons

            Label dragPanel = new Label();
            tdOperations.Controls.Add(dragPanel);
            dragPanel.ID = "mover";
            dragPanel.Text = "&equiv;";
            dragPanel.CssClass = "dragpanel";
            dragPanel.Style["cursor"] = "move";

            //Add a space
            tdOperations.Controls.Add(new LiteralControl("&nbsp;"));

            //Delete button
            LinkButton btnDelete = new LinkButton() { Text = "Delete" };
            tdOperations.Controls.Add(btnDelete);
            btnDelete.CssClass = "ActionLink";
            btnDelete.CommandName = "DeleteParameter";

            //New child button
            LinkButton btnNewChild = new LinkButton() { Text = "New child" };
            tdOperations.Controls.Add(btnNewChild);
            btnNewChild.CommandName = "AddParameterChild";
            btnNewChild.CssClass = "ActionLink";
            //Currently we're not allowing this button as it is felt that it complicates the form
            btnNewChild.Visible = false;

            //Control for associating child with parent (supporting javascript sets hidden fields before postback)
            this._associateLinkButton = new AssociateLinkButtonControl();
            tdOperations.Controls.Add(this._associateLinkButton);
            this._associateLinkButton.ID = "AssociateLinkButton";

            this._parameterPositionControl = new ParameterPositionControl();
            tdOperations.Controls.Add(this._parameterPositionControl);
            this._parameterPositionControl.ID = "ParameterPositionControl";

            //Create the table cells for the data
            row.Controls.Add(this.GetTextBoxTableCell("Name"));

            //Get the value cell and add it
            TableCell valueCell = this.GetLiteralTableCell("Value");
            row.Controls.Add(valueCell);

            //Modify the value cell's textbox size
            TextBox valueBox = valueCell.FindControl("txtValue") as TextBox;
            valueBox.TextMode = TextBoxMode.MultiLine;
            valueBox.CssClass = "hdcfieldlargevalue";

            //Create IsCompulsory checkbox column
            TableCell tdIsCompulsory = new TableCell() { ID = "tdIsCompulsory" };
            row.Controls.Add(tdIsCompulsory);
            CheckBox cbIsCompulsory = new CheckBox() { ID = "cbIsCompulsory" };
            tdIsCompulsory.Controls.Add(cbIsCompulsory);
            cbIsCompulsory.Enabled = this._editMode;

            row.Controls.Add(this.GetTextBoxTableCell("Unit"));
            row.Controls.Add(this.GetTextBoxTableCell("Type"));
            row.Controls.Add(this.GetTextBoxTableCell("Position"));

            //Set up an even so we can add data
            row.DataBinding += new EventHandler(tr_DataBinding);

        }

        private TableCell GetTextBoxTableCell(string name)
        {
            TableCell tableCell = new TableCell() { ID = "td" + name };
            TextBox tableBox = new TextBox() { ID = "txt" + name };
            tableCell.Controls.Add(tableBox);
            Label tableLabel = new Label() { ID = "lbl" + name };
            tableCell.Controls.Add(tableLabel);
            tableBox.Visible = this._editMode;
            tableLabel.Visible = !this._editMode;
            return tableCell;
        }

        private TableCell GetLiteralTableCell(string name)
        {
            TableCell tableCell = new TableCell() { ID = "td" + name };
            TextBox tableBox = new TextBox() { ID = "txt" + name };
            tableCell.Controls.Add(tableBox);
            LiteralControl tableLiteral = new LiteralControl();
            tableCell.Controls.Add(tableLiteral);
            tableLiteral.ID = "ParameterValue";
            tableBox.Visible = this._editMode;
            tableLiteral.Visible = !this._editMode;
            return tableCell;
        }

        private void tr_DataBinding(object sender, EventArgs e)
        {

            TableRow tr = sender as TableRow;
            PlaceHolder ph1 = tr.Parent as PlaceHolder;
            ListViewDataItem listViewDataItem = ph1.NamingContainer as ListViewDataItem;
            ExperimentParameter experimentParameter = listViewDataItem.DataItem as ExperimentParameter;
            if (experimentParameter != null && tr != null && ph1 != null && listViewDataItem != null)
            {
                //Bind the data cells
                this.BindCellData("Name", tr, experimentParameter);
                this.BindLiteralCellData(tr, experimentParameter);
                this.BindCellData("Unit", tr, experimentParameter);
                this.BindCellData("Type", tr, experimentParameter);
                this.BindCellData("Position", tr, experimentParameter);
                this._associateLinkButton.ParentParamIDField.Value = experimentParameter.ID.ToString();
                this._parameterPositionControl.ParamIDToDemoteField.Value = experimentParameter.ID.ToString();

                //Work out whether to check the iscompulsory checkbox
                CheckBox cbIsCompulsory = tr.FindControl("cbIsCompulsory") as CheckBox;
                cbIsCompulsory.Checked = (Boolean)(DataBinder.Eval(experimentParameter, "IsCompulsory") ?? false);

                //Application layer checking of parameter, highlight problems
                if (!experimentParameter.ValueIsValid)
                {
                    //Highlight the value field as missing
                    TableCell tdValue = tr.FindControl("tdValue") as TableCell;
                    tdValue.CssClass = "ParameterValueError";

                    //Investigate further to identify what went wrong and highlight the IsCompulsory and/or Type fields)
                    if (!experimentParameter.ValueIsCompulsoryAndPresent)
                    {
                        TableCell tdIsCompulsory = tr.FindControl("tdIsCompulsory") as TableCell;
                        tdIsCompulsory.CssClass = "ParameterValueError";
                    }

                    if (!experimentParameter.ValueMatchesType)
                    {
                        TableCell tdType = tr.FindControl("tdType") as TableCell;
                        tdType.CssClass = "ParameterValueError";
                    }
                }
            }
            else
            {
                tr.Controls.Add(new Literal() { Text = "Unable to data bind" });
            }
        }

        private bool BindCellData(string fieldName, TableRow row, ExperimentParameter data)
        {
            if (String.IsNullOrEmpty(fieldName) || row == null || data == null)
            {
                return false;
            }
            TextBox textBox = row.FindControl("txt" + fieldName) as TextBox;
            textBox.Text = DataBinder.Eval(data, fieldName, "{0}");
            Label label = row.FindControl("lbl" + fieldName) as Label;
            label.Text = DataBinder.Eval(data, fieldName, "{0}");
            return true;
        }

        private bool BindLiteralCellData(TableRow row, ExperimentParameter data)
        {
            LiteralControl valueLiteralControl = row.FindControl("ParameterValue") as LiteralControl;
            TextBox textBox = row.FindControl("txtValue") as TextBox;
            if (valueLiteralControl == null || textBox == null)
            {
                return false;
            }

            //Set the textbox's value
            textBox.Text = DataBinder.Eval(data, "Value", "{0}");

            //Set the literalcontrol's value
            if (String.IsNullOrEmpty(data.Value))
            {
                //We would like a space to ensure style sheets work 
                valueLiteralControl.Text = "&nbsp;";
            }
            else
            {
                valueLiteralControl.Text = data.GetValueAsParsedHTML();
            }
            return true;
        }
        
    }


}
